package com.example.smartagrisys.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartagrisys.dto.ComplaintDTO;
import com.example.smartagrisys.entity.Complaint;
import com.example.smartagrisys.entity.Notification;
import com.example.smartagrisys.mapper.ComplaintMapper;
import com.example.smartagrisys.service.ComplaintService;
import com.example.smartagrisys.service.NotificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 投诉服务实现类
 */
@Slf4j
@Service
public class ComplaintServiceImpl extends ServiceImpl<ComplaintMapper, Complaint> implements ComplaintService {

    @Autowired
    private NotificationService notificationService;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public List<ComplaintDTO> getBuyerComplaints(Long buyerId) {
        List<Complaint> complaints = baseMapper.selectByBuyerId(buyerId);
        return complaints.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    public List<ComplaintDTO> getSellerComplaints(Long sellerId) {
        List<Complaint> complaints = baseMapper.selectBySellerId(sellerId);
        return complaints.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComplaintDTO createComplaint(ComplaintDTO complaintDTO) {
        Complaint complaint = convertToEntity(complaintDTO);
        
        // 设置初始状态和时间
        complaint.setStatus("pending");
        complaint.setCreateTime(LocalDateTime.now());
        complaint.setUpdateTime(LocalDateTime.now());
        complaint.setDeleted(false);
        
        // 转换图片列表为JSON字符串
        if (complaintDTO.getImages() != null && !complaintDTO.getImages().isEmpty()) {
            try {
                complaint.setImages(objectMapper.writeValueAsString(complaintDTO.getImages()));
            } catch (JsonProcessingException e) {
                log.error("转换图片列表为JSON失败", e);
            }
        }
        
        boolean success = save(complaint);
        if (success) {
            // 创建通知给卖家
            try {
                String title = "收到新投诉";
                String content = "您收到一个新的投诉，标题：" + complaint.getTitle() + "，订单编号：" + complaint.getOrderNumber();
                
                notificationService.createActionNotification(
                    complaint.getSellerId(),
                    title,
                    content,
                    "complaint",
                    "/main/seller/complaints",
                    "查看投诉",
                    "warning"
                );
                
                log.info("已为卖家(ID:{})创建投诉通知", complaint.getSellerId());
            } catch (Exception e) {
                log.error("创建投诉通知失败", e);
                // 不影响主流程
            }
            
            return convertToDTO(complaint);
        }
        
        return null;
    }

    @Override
    public ComplaintDTO getComplaintById(Long id) {
        // 使用关联查询获取完整投诉信息
        Complaint complaint = baseMapper.selectComplaintDetailById(id);
        if (complaint != null) {
            ComplaintDTO dto = convertToDTO(complaint);
            
            // 设置农户名称（如果存在）
            if (complaint.getSellerName() != null) {
                dto.setFarmerName(complaint.getSellerName());
            }
            
            return dto;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateComplaintStatus(Long id, String status) {
        Complaint complaint = getById(id);
        if (complaint == null) {
            return false;
        }
        
        complaint.setStatus(status);
        complaint.setUpdateTime(LocalDateTime.now());
        
        return updateById(complaint);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean replyComplaint(Long id, String replyContent) {
        Complaint complaint = getById(id);
        if (complaint == null) {
            return false;
        }
        
        complaint.setReplyContent(replyContent);
        complaint.setReplyTime(LocalDateTime.now());
        complaint.setStatus("processing");
        complaint.setUpdateTime(LocalDateTime.now());
        
        boolean success = updateById(complaint);
        
        if (success) {
            // 创建通知给买家
            try {
                String title = "投诉回复通知";
                String content = "您的投诉已收到回复，订单编号：" + complaint.getOrderNumber();
                
                notificationService.createActionNotification(
                    complaint.getBuyerId(),
                    title,
                    content,
                    "complaint",
                    "/main/buyer/complaints",
                    "查看详情",
                    "info"
                );
                
                log.info("已为买家(ID:{})创建投诉回复通知", complaint.getBuyerId());
            } catch (Exception e) {
                log.error("创建投诉回复通知失败", e);
                // 不影响主流程
            }
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resolveComplaint(Long id, String solution) {
        Complaint complaint = getById(id);
        if (complaint == null) {
            return false;
        }
        
        complaint.setSolution(solution);
        complaint.setResolveTime(LocalDateTime.now());
        complaint.setStatus("resolved");
        complaint.setUpdateTime(LocalDateTime.now());
        
        boolean success = updateById(complaint);
        
        if (success) {
            // 创建通知给买家
            try {
                String title = "投诉已解决";
                String content = "您的投诉已解决，订单编号：" + complaint.getOrderNumber();
                
                notificationService.createActionNotification(
                    complaint.getBuyerId(),
                    title,
                    content,
                    "complaint",
                    "/main/buyer/complaints",
                    "查看详情",
                    "success"
                );
                
                log.info("已为买家(ID:{})创建投诉解决通知", complaint.getBuyerId());
            } catch (Exception e) {
                log.error("创建投诉解决通知失败", e);
                // 不影响主流程
            }
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean closeComplaint(Long id) {
        Complaint complaint = getById(id);
        if (complaint == null) {
            return false;
        }
        
        complaint.setStatus("closed");
        complaint.setUpdateTime(LocalDateTime.now());
        
        boolean success = updateById(complaint);
        
        if (success) {
            // 创建通知给买家和卖家
            try {
                String title = "投诉已关闭";
                String content = "投诉已关闭，订单编号：" + complaint.getOrderNumber();
                
                // 给买家发通知
                notificationService.createSystemNotification(
                    complaint.getBuyerId(),
                    title,
                    content,
                    "complaint"
                );
                
                // 给卖家发通知
                notificationService.createSystemNotification(
                    complaint.getSellerId(),
                    title,
                    content,
                    "complaint"
                );
                
                log.info("已为买家(ID:{})和卖家(ID:{})创建投诉关闭通知", complaint.getBuyerId(), complaint.getSellerId());
            } catch (Exception e) {
                log.error("创建投诉关闭通知失败", e);
                // 不影响主流程
            }
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean followUpComplaint(Long id, String content) {
        Complaint complaint = getById(id);
        if (complaint == null) {
            return false;
        }
        
        // 追加内容到原有投诉内容
        String updatedContent = complaint.getContent();
        if (!StringUtils.hasLength(updatedContent)) {
            updatedContent = "";
        }
        
        LocalDateTime now = LocalDateTime.now();
        updatedContent += "\n\n--- 买家追加 (" + now + ") ---\n" + content;
        
        complaint.setContent(updatedContent);
        complaint.setUpdateTime(now);
        
        // 如果投诉已关闭，则重新打开
        if ("closed".equals(complaint.getStatus())) {
            complaint.setStatus("processing");
        }
        
        boolean success = updateById(complaint);
        
        if (success) {
            // 创建通知给卖家
            try {
                String title = "投诉有新的跟进";
                String contentMsg = "买家对订单编号为 " + complaint.getOrderNumber() + " 的投诉进行了跟进";
                
                notificationService.createActionNotification(
                    complaint.getSellerId(),
                    title,
                    contentMsg,
                    "complaint",
                    "/main/seller/complaints",
                    "查看详情",
                    "warning"
                );
                
                log.info("已为卖家(ID:{})创建投诉跟进通知", complaint.getSellerId());
            } catch (Exception e) {
                log.error("创建投诉跟进通知失败", e);
                // 不影响主流程
            }
        }
        
        return success;
    }

    @Override
    public ComplaintDTO convertToDTO(Complaint complaint) {
        if (complaint == null) {
            return null;
        }
        
        ComplaintDTO dto = new ComplaintDTO();
        BeanUtils.copyProperties(complaint, dto);
        
        // 修正字段名差异
        dto.setFarmerId(complaint.getSellerId());
        dto.setFarmerName(complaint.getSellerName());
        dto.setCreateDate(complaint.getCreateTime());
        dto.setUpdateDate(complaint.getUpdateTime());
        dto.setReplyDate(complaint.getReplyTime());
        dto.setResolveDate(complaint.getResolveTime());
        
        // 转换图片字符串为图片列表
        if (StringUtils.hasLength(complaint.getImages())) {
            try {
                dto.setImages(objectMapper.readValue(complaint.getImages(), 
                    new TypeReference<List<String>>() {}));
            } catch (Exception e) {
                log.error("解析图片JSON失败", e);
                dto.setImages(new ArrayList<>());
            }
        } else {
            dto.setImages(new ArrayList<>());
        }
        
        return dto;
    }

    @Override
    public Complaint convertToEntity(ComplaintDTO dto) {
        if (dto == null) {
            return null;
        }
        
        Complaint entity = new Complaint();
        BeanUtils.copyProperties(dto, entity);
        
        // 修正字段名差异
        entity.setSellerId(dto.getFarmerId());
        entity.setSellerName(dto.getFarmerName());
        entity.setCreateTime(dto.getCreateDate());
        entity.setUpdateTime(dto.getUpdateDate());
        entity.setReplyTime(dto.getReplyDate());
        entity.setResolveTime(dto.getResolveDate());
        
        // 转换图片列表为JSON字符串
        if (dto.getImages() != null && !dto.getImages().isEmpty()) {
            try {
                entity.setImages(objectMapper.writeValueAsString(dto.getImages()));
            } catch (JsonProcessingException e) {
                log.error("转换图片列表为JSON失败", e);
            }
        }
        
        return entity;
    }
} 